package com.wtwd.campus.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wtwd.campus.common.RespCode;
import com.wtwd.campus.constant.ManLanguageEnum;
import com.wtwd.campus.constant.OrgTypeEnum;
import com.wtwd.campus.dao.SchoolMapper;
import com.wtwd.campus.dao.SysOrgMapper;
import com.wtwd.campus.dao.SysRoleMapper;
import com.wtwd.campus.entity.School;
import com.wtwd.campus.entity.SysOrg;
import com.wtwd.campus.entity.SysOrgPermission;
import com.wtwd.campus.entity.SysRole;
import com.wtwd.campus.model.vo.OrgTreeVO;
import com.wtwd.campus.model.vo.PermissionTreeVO;
import com.wtwd.campus.model.vo.ResultVO;
import com.wtwd.campus.model.vo.SysOrgVO;
import com.wtwd.campus.service.ClassService;
import com.wtwd.campus.service.GradeService;
import com.wtwd.campus.service.SysOrgService;
import com.wtwd.campus.service.SysPermissionService;
import com.wtwd.campus.utils.LevelNoUtitl;
import com.wtwd.campus.utils.TreeUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zdl
 * @since 2021-06-08
 */
@Service
public class SysOrgServiceImpl implements SysOrgService {
    @Resource
    private SysOrgMapper sysOrgMapper;

    @Resource
    private SysPermissionService sysPermissionService;

    @Resource
    private GradeService gradeService;

    @Resource
    private ClassService classService;

    @Resource
    private SysRoleMapper sysRoleMapper;

    @Resource
    private SchoolMapper schoolMapper;

    @Override
    public IPage<SysOrgVO> queryPage(Page<SysOrg> page, SysOrg sysOrg) {
        return sysOrgMapper.querylist(page, sysOrg);
    }

    /**
     * 保存部门
     * 1.创建组织编号
     *
     * @param sysOrg
     * @return
     */
    @Override
    public ResultVO save(SysOrg sysOrg) {
        if (sysOrg.getPid() == null) {
            sysOrg.setPid(0);
        }
        if (sysOrg.getOrgType() == null) {
            sysOrg.setOrgType("1");
        }
        String oryCode = createOryCode(sysOrg.getPid());
        sysOrg.setOrgCode(oryCode);
        sysOrgMapper.insert(sysOrg);
        return ResultVO.ok(sysOrg);
    }

    @Override
    public ResultVO updateById(SysOrg sysOrg) {
        sysOrg.setOrgCode(null);
        sysOrg.setPid(null);
        sysOrgMapper.updateById(sysOrg);
        return ResultVO.ok();
    }

    @Override
    public ResultVO deleteById(Integer id) {
        if (listLowerOrgByPid(id).size() > 0) {
            return ResultVO.error(RespCode.ORG_DEL_LIMIT);
        }
        if (new LambdaQueryChainWrapper<>(sysRoleMapper)
                .eq(SysRole::getOrgId, id)
                .count() > 0) {
            return ResultVO.error(RespCode.ORG_EXIST_ROLE);
        }
        if (new LambdaQueryChainWrapper<>(schoolMapper)
                .eq(School::getOrgId, id)
                .count() > 0) {
            return ResultVO.error(RespCode.ORG_EXIST_SCHOOL);
        }
        sysOrgMapper.deleteById(id);
        sysOrgMapper.deleteOrgPermissionByOrgId(id);
        return ResultVO.ok();
    }

    @Override
    public List<SysOrg> listLowerOrgByPid(Integer pid) {
        return sysOrgMapper.listOrgByPid(pid);
    }

    /**
     * 每次更新都是全量更新
     * 1.查询出原有权限,比较出删除的权限
     * 2.删除该组织所有权限,及其下属组织和角色被删除的权限
     * 3.批量插入所有权限
     *
     * @param orgId
     * @param permissionIds
     * @return
     */

    @Override
    public ResultVO saveOrgPermissionBatch(Integer orgId, String orgCode, String permissionIds) {
        List<Integer> orgPermissionIds = getOrgPermissionIdsByOrgId(orgId);
        String[] split = permissionIds.split(",");
        List<Integer> delPermission = orgPermissionIds.stream().filter(id -> {
            for (String s : split) {
                if (id.equals(Integer.valueOf(s))) {
                    return false;
                }
            }
            return true;

        }).collect(Collectors.toList());
        if (delPermission.size() > 0) {
            //获取所有下级组织,和角色
            List<OrgTreeVO> orgTreeVOS = sysOrgMapper.listOrgIncludeSchoolByOrgCode(orgCode);
            if(orgTreeVOS.size()>0){
                List<Integer> orgIds = orgTreeVOS.stream().map(OrgTreeVO::getId).collect(Collectors.toList());
                sysOrgMapper.deleteOrgPermissionByOrgIdsAndPermissionIds(orgIds, delPermission);
            }
            List<SysRole> role = new LambdaQueryChainWrapper<>(sysRoleMapper)
                    .likeRight(SysRole::getOrgCode, orgCode)
                    .list();
            if(role.size()>0){
                List<Integer> roleIds = role.stream().map(SysRole::getId).collect(Collectors.toList());
                sysRoleMapper.deleteRolePermissionByRoleIdsAndPermissionIds(roleIds,delPermission);
            }

        }
        sysOrgMapper.deleteOrgPermissionByOrgId(orgId);
        ArrayList<SysOrgPermission> sysOrgPermissions = new ArrayList<>();
        for (String s : split) {
            SysOrgPermission sysOrgPermission = new SysOrgPermission();
            sysOrgPermission.setOrgId(orgId);
            sysOrgPermission.setPermissionId(Integer.valueOf(s));
            sysOrgPermissions.add(sysOrgPermission);
        }
        sysOrgMapper.saveOrgPermissionBatch(sysOrgPermissions);
        return ResultVO.ok();
    }


    @Override
    public ResultVO getOrgTreeByOrgCode(String orgCode) {
        List<OrgTreeVO> treeData = listOwnOrgByOrgCode(orgCode).stream().map(data -> {
            OrgTreeVO orgTreeVO = new OrgTreeVO();
            orgTreeVO.setId(data.getId());
            orgTreeVO.setName(data.getOrgName());
            orgTreeVO.setType(data.getOrgType());
            orgTreeVO.setPid(data.getPid());
            orgTreeVO.setOrgCode(data.getOrgCode());
            return orgTreeVO;
        }).collect(Collectors.toList());
        return ResultVO.ok(TreeUtil.createTree(treeData));
    }

    @Override
    public ResultVO getOrgTreeByOrgCode(String orgCode, Integer showOrgType) {
        List<OrgTreeVO> treeData;
        switch (OrgTypeEnum.getOryType(String.valueOf(showOrgType))) {
            case ORG_SCHOOL://包含学校的组织树
                treeData = sysOrgMapper.listOrgIncludeSchoolByOrgCode(orgCode);
                break;
            case ORG_GRADE: //包含年级
                treeData = listOrgIncludeGradeByOrgCode(orgCode);
                break;
            case ORG_CLASS:
                treeData = listOrgIncludeClassByOrgCode(orgCode);
                break;
            default: //默认显示组织类型
                return getOrgTreeByOrgCode(orgCode);
        }
        return ResultVO.ok(TreeUtil.createTreeByType(treeData));
    }

    private List<OrgTreeVO> listOrgIncludeGradeByOrgCode(String orgCode) {
        List<OrgTreeVO> datas = sysOrgMapper.listOrgIncludeSchoolByOrgCode(orgCode);
        List<Integer> schoolIds = datas.stream().filter(orgTreeVO -> OrgTypeEnum.ORG_SCHOOL.getType().equals(orgTreeVO.getType()))
                .map(OrgTreeVO::getId).collect(Collectors.toList());
        if (schoolIds.size() > 0) {
            gradeService.listGradeBySchoolIds(schoolIds).forEach(item -> {
                OrgTreeVO orgTreeVO = new OrgTreeVO();
                orgTreeVO.setId(item.getGradeId());
                orgTreeVO.setName(item.getGradeName());
                orgTreeVO.setType(OrgTypeEnum.ORG_GRADE.getType());
                orgTreeVO.setPid(item.getSchoolId());
                datas.add(orgTreeVO);
            });
        }
        return datas;
    }

    private List<OrgTreeVO> listOrgIncludeClassByOrgCode(String orgCode) {
        List<OrgTreeVO> datas = listOrgIncludeGradeByOrgCode(orgCode);
        List<Integer> collect = datas.stream().filter(orgTreeVO -> OrgTypeEnum.ORG_GRADE.getType().equalsIgnoreCase(orgTreeVO.getType()))
                .map(OrgTreeVO::getId).collect(Collectors.toList());
        if (collect.size() > 0) {
            classService.listClassByGradeIds(collect).forEach(item -> {
                OrgTreeVO orgTreeVO = new OrgTreeVO();
                orgTreeVO.setId(item.getClassesId());
                orgTreeVO.setName(item.getClassesName());
                orgTreeVO.setType(OrgTypeEnum.ORG_CLASS.getType());
                orgTreeVO.setPid(item.getGradeId());
                datas.add(orgTreeVO);
            });
        }
        return datas;
    }

    @Override
    public List<SysOrg> listOwnOrgByOrgCode(String orgCode) {
        return sysOrgMapper.listOrgByOrgCode(orgCode);
    }

    /**
     * 如果是顶级组织则获取所有权限
     *
     * @param orgId
     * @return
     */
    @Override
    public ResultVO getOrgPermissionTreeByOrgId(Integer orgId,Integer type) {
        SysOrg sysOrg = sysOrgMapper.selectById(orgId);
        if (sysOrg == null) {
            return ResultVO.error(RespCode.PARAMS_ERROR);
        }
        if (0 == sysOrg.getPid()) {
            return sysPermissionService.getAllPermissionTree(type);
        }
        List<PermissionTreeVO> tree = sysOrgMapper.listOrgPermissionByOrgId(orgId);
        if (type!=null){
            if (type.equals(ManLanguageEnum.EN.getType())){
                tree.stream().forEach(e->{
                    if(StringUtils.isNotBlank(e.getEn())){
                        e.setName(e.getEn());
                    }
                });
            }
        }
        // 如果是二级组织，则其组织权限去掉 导入设备; 二级组织orgCode A01A01
        int charactersCount = 0;
        char[] chars = sysOrg.getOrgCode().toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] > 'A' && chars[i] < 'Z') {
                charactersCount++;
            }
        }
        if (charactersCount == 2) {
            // 权限id 19表示 设备导入权限
            tree = tree.stream().filter(p -> p.getId() != 19).collect(Collectors.toList());
        }
        return ResultVO.ok(TreeUtil.createTree(tree));
    }

    @Override
    public Map<Integer, String> getOrgNamesByOrgIds(List<Integer> orgIds) {
        List<SysOrg> sysOrgs = sysOrgMapper.selectBatchIds(orgIds);
        Map<Integer, String> map = new HashMap<>();
        sysOrgs.forEach(data -> map.put(data.getId(), data.getOrgName()));
        return map;
    }

    @Override
    public List<Integer> getOrgPermissionIdsByOrgId(Integer orgId) {
        return sysOrgMapper.listOrgPermissionByOrgId(orgId).stream().map(PermissionTreeVO::getId).collect(Collectors.toList());
    }

    @Override
    public String getOrgCodeById(Integer orgId) {
        return sysOrgMapper.getOrgCodeById(orgId);
    }

    @Override
    public SysOrg getSysOrgByOrgCode(String orgCode) {
        return sysOrgMapper.getSysOrgByOrgCode(orgCode);
    }

    @Override
    public SysOrg getSysOrgById(Integer orgId) {
        return sysOrgMapper.getSysOrgById(orgId);
    }

    @Override
    public List<SysOrg> getOverdueSysOrg(long time) {
        return sysOrgMapper.getOverdueSysOrg(time);
    }

    @Override
    public List<Map<String, Object>> getExpirationOrg(Long timeMax,Long timeMin) {
        return sysOrgMapper.getExpirationOrg(timeMax,timeMin);
    }

    @Override
    public int renewSysOrgAndSub(int orgId, Long expireTime) {
        String orgCode = sysOrgMapper.getOrgCodeById(orgId);
        return sysOrgMapper.renewSysOrgAndSub(orgCode, expireTime);
    }

    /**
     * 生成组织编号
     *
     * @param pid
     * @return
     */
    private String createOryCode(Integer pid) {
        String orgCode;
        if (pid == null) {
            return null;
        }
        //获取同级组织
        List<SysOrg> sysOrgs = listLowerOrgByPid(pid);
        if (sysOrgs.size() == 0) {//同级第一个
            //获取父组织
            SysOrg sysOrg = sysOrgMapper.selectById(pid);
            if (sysOrg == null) {//顶级组织
                orgCode = "";
            } else {
                orgCode = sysOrg.getOrgCode();
            }
            orgCode = LevelNoUtitl.getStartNo(orgCode);
        } else {
            orgCode = LevelNoUtitl.getNextNo(sysOrgs.get(0).getOrgCode());
        }
        return orgCode;
    }


}
